package com.trail2peak.pdi.fastjsoninput; import java.io.InputStream; import java.net.URL; import java.util.List; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.vfs.KettleVFS; import org.pentaho.di.i18n.BaseMessages; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Option; import com.jayway.jsonpath.ParseContext; import com.jayway.jsonpath.ReadContext; /** * @author Samatar * @author edube * @author jadametz * @since 2015-08-18 */ public class FastJsonReader { private static Class<?> PKG = FastJsonInputMeta.class; // for i18n purposes, // needed by // Translator2!! // as per RFC 7159, the default JSON encoding shall be UTF-8 // see https://tools.ietf.org/html/rfc7159#section-8.1 private final static String JSON_CHARSET = "UTF-8"; private ReadContext jsonReadContext; private Configuration jsonConfiguration; private boolean ignoreMissingPath; private boolean defaultPathLeafToNull; public FastJsonReader() throws KettleException { this.ignoreMissingPath = false; this.defaultPathLeafToNull = false; jsonConfiguration = Configuration.defaultConfiguration().addOptions( Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS); } public void setIgnoreMissingPath(boolean value) { this.ignoreMissingPath = value; } public void setDefaultPathLeafToNull(boolean value) { this.defaultPathLeafToNull = value; if (this.defaultPathLeafToNull) { jsonConfiguration = Configuration.defaultConfiguration().addOptions( Option.ALWAYS_RETURN_LIST, Option.SUPPRESS_EXCEPTIONS, Option.DEFAULT_PATH_LEAF_TO_NULL); } } private ParseContext getParseContext() { return JsonPath.using(jsonConfiguration); } private ReadContext getReadContext() { return jsonReadContext; } public void readFile(String filename) throws KettleException { InputStream is = null; try { is = KettleVFS.getInputStream(filename); jsonReadContext = getParseContext().parse(is, JSON_CHARSET); if (jsonReadContext == null) { throw new Exception(BaseMessages.getString(PKG, "FastJsonReader.Error.ReadFile.Null")); } } catch (Exception e) { throw new KettleException(BaseMessages.getString(PKG, "FastJsonReader.Error.ParsingFile", e)); } finally { try { if (is != null) { is.close(); } } catch (Exception e) { // Ignore errors } } } public void readString(String value) throws KettleException { try { jsonReadContext = getParseContext().parse(value); if (jsonReadContext == null) { throw new Exception(BaseMessages.getString(PKG, "FastJsonReader.Error.ReadString.Null")); } } catch (Exception e) { throw new KettleException(BaseMessages.getString(PKG, "FastJsonReader.Error.ParsingString", e)); } } public void readUrl(String value) throws KettleException { InputStream is = null; try { URL url = new URL(value); is = url.openConnection().getInputStream(); jsonReadContext = getParseContext().parse(is, JSON_CHARSET); if (jsonReadContext == null) { throw new Exception(BaseMessages.getString(PKG, "FastJsonReader.Error.ReadUrl.Null")); } } catch (Exception e) { throw new KettleException(BaseMessages.getString(PKG, "FastJsonReader.Error.ParsingUrl", e)); } finally { try { if (is != null) { is.close(); } } catch (Exception e) { // Ignore errors } } } public JsonResultList getPath(String path) throws KettleException { JsonResultList ja; try { List<Object> ls = getReadContext().read(path); if (ls != null && !ls.isEmpty()) { ja = new JsonResultList(ls); } else { if (!isIgnoreMissingPath()) { throw new KettleException(BaseMessages.getString(PKG, "FastJsonReader.Error.CanNotFindPath", path)); } // The Json Path is missing // and user do not want to fail // so we need to populate it with NULL values ja = new JsonResultList(); ja.setNull(true); } } catch (Exception e) { throw new KettleException(e); } return ja; } public boolean isIgnoreMissingPath() { return this.ignoreMissingPath; } }